package com.example.demo.Service;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.example.demo.Common.Enum.VisibleScope;
import com.example.demo.Entity.FriendChart;
import com.example.demo.Entity.HistoryVersion;
import com.example.demo.Entity.Note;
import com.example.demo.Mapper.DirectoryMapper;
import com.example.demo.Mapper.FriendChartMapper;
import com.example.demo.Mapper.HistoryVersionMapper;
import com.example.demo.Mapper.NoteMapper;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class NoteServiceImp implements NoteService{
    //public void insertNote(Note note);
    @Autowired
    private NoteMapper noteMapper;
    @Autowired
    private HistoryVersionMapper historyVersionMapper;
    @Autowired
    private FriendChartMapper friendChartMapper;
    @Autowired
    private DirectoryMapper directoryMapper;

    /** 查询笔记 */
    @Override
    public Note selectByNoteId(@RequestParam Integer id) {
        return noteMapper.selectById(id);
    }

    /** 通过用户ID查询所有笔记 */
    @Override
    public List<Note> findByUserId(Integer userId) {
        List<Integer> noteIdList  = noteMapper.selectList(new QueryWrapper<Note>()
                        .eq("user_id", userId))
                .stream().map(Note::getNoteId).toList();

        Set<Integer> directoryIdList = historyVersionMapper.selectList((new QueryWrapper<HistoryVersion>()
                        .in("note_id",noteIdList)))
                .stream().map(HistoryVersion::getDirectoryId).collect(Collectors.toSet());

        List<Integer> result = historyVersionMapper.selectList(new QueryWrapper<HistoryVersion>()
                        .in("directory_id",directoryIdList)
                        .in("note_id",getNewVersionId()))
                .stream().map(HistoryVersion::getNoteId).toList();

        return noteMapper.selectList(new QueryWrapper<Note>()
                .in("note_id",result));
    }

    /** 标签搜索 */
    @Override
    public List<Note> selectByTags(String tag){
        String tags="%"+tag+"%";
        return noteMapper.findByTag(tags);
    }

    /** 标题搜索 */
    @Override
    public List<Note> selectByTitle(String title){
        return noteMapper.findByTitle(title);
    }

    //随机生成
    public static int getRandomNumberNotInList(List<Integer> list) {
        HashSet<Integer> set = new HashSet<>(list);
        Random random = new Random();
        int randomNumber;

        do {
            randomNumber = random.nextInt(1000,9999); // 生成0到99之间的随机数
        } while (set.contains(randomNumber));

        return randomNumber;
    }

    /** 新增笔记 */
    @Override
    public void insertNote(Note note) {
        QueryWrapper<Note> wrapper = new QueryWrapper<Note>()
                .like("file", note.getFile().substring(0, note.getFile().lastIndexOf(".note")));
        int version = noteMapper.selectList(wrapper).size();
        //修改名称
        note.setFile(note.getFile()
                .substring(0, note.getFile()
                        .lastIndexOf(".note"))+"-version" +Integer.toString(version+1) +".note");
        noteMapper.insert(note);

        System.out.println(note.getNoteId()+"2");
        System.out.println(version);
        //插入相应版本信息
        if(version==0){
            List<Integer> list = historyVersionMapper.selectList(null)
                    .stream().map(HistoryVersion::getDirectoryId)
                    .distinct().collect(Collectors.toList());
            int randomNumber = getRandomNumberNotInList(list);
            historyVersionMapper.insert(new HistoryVersion(note.getNoteId(),randomNumber,version+1));
        }
        else
        {
            int needId = 0;
            List<Note> noteList = noteMapper.selectList(wrapper);
            for (Note n : noteList) {
                if(!(n.getNoteId() == note.getNoteId())){
                    needId = n.getNoteId();
                    break;
                }
            }

            System.out.println("needId:"+needId);
            QueryWrapper<HistoryVersion> historyVersionQueryWrapper = new QueryWrapper<HistoryVersion>()
                    .eq("note_id", needId);
            List<HistoryVersion> historyVersionList = historyVersionMapper.selectList(historyVersionQueryWrapper);
            historyVersionMapper.insert(new HistoryVersion
                    (note.getNoteId(),historyVersionList.get(0).getDirectoryId(),version+1));
        }

    }

    /** 删除笔记 */
    public void removeById(Integer id){
        //noteMapper.deleteById(id);
        Note note = noteMapper.selectById(id);
        String filename = note.getFile().substring(0, note.getFile().lastIndexOf("-version"));
        Integer directoryId = historyVersionMapper.selectList(new QueryWrapper<HistoryVersion>().eq("note_id", id))
                .get(0).getDirectoryId();
        historyVersionMapper.delete(new QueryWrapper<HistoryVersion>().eq("directory_id", directoryId));
        directoryMapper.deleteByNoteId(id);

        QueryWrapper<Note> wrapper = new QueryWrapper<Note>()
                .like("file", filename);
        List<Note> deleteNoteList = noteMapper.selectList(wrapper);
        noteMapper.delete(wrapper);
        for(Note n : deleteNoteList){
            File f = new File(uploadDir + n.getFile());
            f.delete();
        }
    }

    /** 更新笔记 */
    @Override
    public void saveOrUpdateNote(Note note) {
        noteMapper.insertOrUpdate(note);
    }


    //得到最新版本信息
    public List<Integer> getNewVersionId(){
        List<HistoryVersion> historyVersionList = historyVersionMapper.selectList(null);
        Map<Integer, Optional<HistoryVersion>> groupedItems = historyVersionList.stream()
                .collect(Collectors
                        .groupingBy(HistoryVersion::getDirectoryId, Collectors
                                .maxBy(Comparator.comparingInt(HistoryVersion::getVersion))));

        List<HistoryVersion> maxHistoryVersion = new ArrayList<>();
        for (Map.Entry<Integer, Optional<HistoryVersion>> entry : groupedItems.entrySet()) {
            if (entry.getValue().isPresent()) {
                maxHistoryVersion.add(entry.getValue().get());
            }
        }
        return maxHistoryVersion.stream()
                .map(HistoryVersion::getNoteId).toList();
    }

    //得到条件
    public QueryWrapper<Note> getWrapper(List<Integer> query, String content) {
        List<String> ifQuery = new ArrayList<String>();
        for (int i = 0; i < query.size(); i++) {
            if (query.get(i) == 1) {
                ifQuery.add(content);
            } else {
                ifQuery.add(null);
            }
        }

        if(ifQuery.get(3)==null){
            ifQuery.remove(3);
            ifQuery.add("无效数据");
        }

        List<Integer> noteIdList = getNewVersionId();

        System.out.println(ifQuery);
        QueryWrapper<Note> wrapper = new QueryWrapper<Note>()
                .in("note_id", noteIdList)
                .and(i -> i.like("title", ifQuery.get(0))
                        .or().like("summary", ifQuery.get(1))
                        .or().inSql("user_id", "select id from user where name like '%" + ifQuery.get(2) + "%'")
                        .or().like("note_tags", ifQuery.get(3)));
        return wrapper;
    }

    /** 查询算法 */
    @Override
    public List<Note> select(List<Integer> query,String scope,String content,Integer userId) {
        QueryWrapper<FriendChart> friendWrapper = new QueryWrapper<FriendChart>()
                .eq("self_id", userId);
        List<Integer> friendList;

        System.out.println(userId);

        friendList = noteMapper.findFriendId(userId);
        if(friendList==null){
            friendList = new ArrayList<Integer>();
        }
        friendList.add(userId);

        System.out.println(friendList);
        QueryWrapper<Note> friendNoteQueryWrapper = getWrapper(query,content)
                .in("user_id",friendList);

        QueryWrapper<Note> ownNoteQueryWrapper = getWrapper(query,content)
                .eq("user_id",userId);

        //查询范围
        if(VisibleScope.selfScope.getValue().equals(scope)) {
            return noteMapper.selectList(ownNoteQueryWrapper);
        }
        else if (VisibleScope.friendScope.getValue().equals(scope))
        {
            List<Note> result = noteMapper.selectList(friendNoteQueryWrapper);
            List<Note> removeList = new ArrayList<>();
            if(result!=null && !result.isEmpty()) {
                for (Note note : result) {
                    if (friendList.contains(note.getUserId()) && !Objects.equals(note.getUserId(), userId) && note.getVisibleScope().equals(VisibleScope.selfScope)) {
                        removeList.add(note);
                    }
                }
            }

            if(!removeList.isEmpty()) {
                for (Note note : removeList) {
                    result.remove(note);
                }
            }
            return result;
        }
        else
        {
            List<Note> friendNoteList = noteMapper.selectList(friendNoteQueryWrapper);
            System.out.println(friendNoteList);
            List<Note> removeList = new ArrayList<>();
            if(friendNoteList!=null && !friendNoteList.isEmpty()) {
                for (Note note : friendNoteList) {
                    if (friendList.contains(note.getUserId()) && !Objects.equals(note.getUserId(), userId) && note.getVisibleScope()==VisibleScope.selfScope) {
                        removeList.add(note);
                    }
                }
            }

            if(!removeList.isEmpty()) {
                for (Note note : removeList) {
                    friendNoteList.remove(note);
                }
            }

            List<Note> result = noteMapper.selectList(getWrapper(query,content)
                    .notIn("user_id",friendList)
                    .eq("visible_scope",VisibleScope.publicScope.getValue()));

            if (friendNoteList != null) {
                System.out.println("我的friendList"+friendNoteList.stream().map(Note::getNoteId).toList());
            }
            System.out.println("我的publicList"+result.stream().map(Note::getNoteId).toList());

            if (friendNoteList != null) {
                result.addAll(friendNoteList);
            }
            System.out.println(result);
            return result;
        }
    }


    //下载路径
    private String uploadDir = System.getProperty("user.dir") + "/noteFiles/";


    /** 存储文件 */
    @Override
    public void takeFile(MultipartFile file) throws Exception{
        File file1 = new File(uploadDir);
        String fileName = file.getOriginalFilename();
        if (fileName != null) {
            System.out.println(fileName.substring(0, fileName.lastIndexOf(".note")));
        }
        Integer noteId = 0;
        Integer directoryId = 0;
        int version = 0;
        if(noteMapper.exists(new QueryWrapper<Note>()
                .like("file", fileName.substring(0, fileName.lastIndexOf(".note")))))
        {
            noteId = noteMapper.selectList(new QueryWrapper<Note>()
                .like("file", fileName.substring(0, fileName.lastIndexOf(".note"))))
                .get(0).getNoteId();

            directoryId = historyVersionMapper.selectOne(new QueryWrapper<HistoryVersion>()
                .eq("note_id", noteId)).getDirectoryId();

            version = historyVersionMapper.selectList(new QueryWrapper<HistoryVersion>()
                        .eq("directory_id",directoryId))
                .stream().mapToInt(HistoryVersion::getVersion)
                .max().orElse(0);
        }else {
            version = 1;
        }

        File file2 = new File(uploadDir, file.getOriginalFilename().substring(0, file.getOriginalFilename()
                .lastIndexOf(".note"))+"-version" +Integer.toString(version) +".note");
        if(!file1.exists())
        {
            file1.mkdirs();
        }

        if(!file2.exists())
        {
            file2.createNewFile();
        }
        file.transferTo(file2);
    }

    /** 下载文件 */
    @Override
    public void download(String fileName, HttpServletResponse response) throws Exception {
        OutputStream os;
        try {
            if (StrUtil.isNotEmpty(fileName)) {
                response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
                response.setContentType("application/octet-stream");
                byte[] bytes = FileUtil.readBytes(uploadDir + fileName);
                os = response.getOutputStream();
                os.write(bytes);
                os.flush();
                os.close();
            }
        } catch (Exception e) {
            System.out.println("文件下载失败");
        }
    }

    /** 找到用户信息 */
    @Override
    public JSONObject findNameById(Integer noteId){
        System.out.println(JSONUtil.parseObj(noteMapper.findNameById(noteId)));
        JSONObject result = JSONUtil.parseObj(noteMapper.findNameById(noteId));
        return result;
    }

    /** 笔记点赞 */
    @Override
    public void upvote(Integer noteId){
        UpdateWrapper<Note> wrapper = new UpdateWrapper<Note>()
                .eq("note_id", noteId)
                .setSql("like_num=like_num+1");
        noteMapper.update(wrapper);
    }

    /** 笔记取消点赞 */
    @Override
    public void cancelUpvote(Integer noteId){
        UpdateWrapper<Note> wrapper = new UpdateWrapper<Note>()
                .eq("note_id", noteId)
                .setSql("like_num=like_num-1");
        noteMapper.update(wrapper);
    }

    /** 查看所有历史版本笔记 */
    @Override
    public List<Note> findAll(Integer noteId){
        Integer directoryId = historyVersionMapper.selectOne(new QueryWrapper<HistoryVersion>()
        .eq("note_id", noteId)).getDirectoryId();

        return noteMapper.selectList(new QueryWrapper<Note>()
                .in("note_id",historyVersionMapper.selectList(new QueryWrapper<HistoryVersion>()
                        .eq("directory_id",directoryId))
                        .stream().map(HistoryVersion::getNoteId).toList()));
    }

    /** 查看最新版本笔记 */
    @Override
    public Note findByNoteId(Integer noteId){
        Integer directoryId = historyVersionMapper.selectOne(new QueryWrapper<HistoryVersion>()
                .eq("note_id", noteId)).getDirectoryId();

        Integer needNoteId = historyVersionMapper.selectOne(new QueryWrapper<HistoryVersion>()
                .eq("directory_id",directoryId)
                .in("note_id",getNewVersionId()))
                .getNoteId();

        return noteMapper.selectOne(new QueryWrapper<Note>()
                .eq("note_id",noteId));
    }
}